#include "SEL.h"

using namespace SEL;

class QuitEventHandler : public EventHandler
{
    virtual bool handleQuitEvent ()
    {
        exit (0);
        return true;
    }

    virtual bool handleKeyPressEvent (SDL::keysym &keysym)
    {
        exit (0);
        return true;
    }
};

Display *screen;
QuitEventHandler quit_handler;

void drawBackgroundPattern (Surface *surface)
{
    for (int i=0; i<surface->h (); i+=2)
    {
        surface->fillRect( Rect(0, i, surface->w (), 1), i%255, 1-i%255, (i/2)%255 );
        surface->fillRect( Rect(0, i+1, surface->w (), 1), 1-i%255, i%255, (i/2)%255 );
    }
}

const int num_blits = 100000;
const int blit_rect_width = 20;
const int blit_rect_height = 20;

int main (int argc, char **argv)
{
    try
    {
        init(INIT_VIDEO);

        atexit(quit);

        screen = new SEL::Display(640, 480, 16, SDL::SWSURFACE);

        srand(500);

        int i=0;

        std::cout << "Doing " << num_blits << " blits (" << blit_rect_width << " x "
        << blit_rect_height << ") - video surface" << std::endl;

        drawBackgroundPattern(screen);

        int old_ticks = SDL::GetTicks();
        int update_time = 0;

        for (i=0; i<num_blits; i++)
        {
            Event::handleEvents (quit_handler);
            Rect srcrect (rand () % (screen->w ()-blit_rect_width),
                          rand () % (screen->h ()-blit_rect_height),
                          blit_rect_width, blit_rect_height);
            Rect dstrect (rand () % (screen->w ()-blit_rect_width),
                          rand () % (screen->h ()-blit_rect_height),
                          blit_rect_width, blit_rect_height);
            screen->blit(screen, srcrect, dstrect);
            int tmp = SDL::GetTicks();
            screen->updateRect(dstrect);
            update_time += SDL::GetTicks()-tmp;

        }

        int video_time = SDL::GetTicks() - old_ticks;

        std::cerr << "Took: " << video_time << "ms";
        std::cerr << " (Blitting : " << video_time - update_time << ", updating: " << update_time << ")" << std::endl;

        Surface *mem_surface = new Surface(SDL::SWSURFACE, screen->w (), screen->h (), *screen->format ());

        std::cout << "Doing " << num_blits << " blits (" << blit_rect_width << " x "
        << blit_rect_height << ") - memory surface" << std::endl;

        old_ticks = SDL::GetTicks ();

        drawBackgroundPattern (mem_surface);

        for (i=0; i<num_blits; i++)
        {
            Event::handleEvents (quit_handler);
            Rect srcrect (rand() % (screen->w()-blit_rect_width),
                          rand() % (screen->h()-blit_rect_height),
                          blit_rect_width, blit_rect_height);
            Rect dstrect (rand() % (screen->w()-blit_rect_width),
                          rand() % (screen->h()-blit_rect_height),
                          blit_rect_width, blit_rect_height);
            mem_surface->blit (mem_surface, srcrect, dstrect);
        }

        int memory_time = SDL::GetTicks() - old_ticks;
        std::cerr << "Took: " << memory_time << "ms" << std::endl;

    }
    catch (Error error)
    {
        std::cout << "Exception caught: " << error.str() << std::endl;
    }

    return 0;
}
